package com.lz.ui_lib.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 涂鸦画板
 * <p/>
 * Created by Liuyk on 2016/1/18.
 */
public class PaletteView extends View {

    /**
     * 画笔颜色，默认是红色
     */
    private int mPaintColor = Color.RED;

    private boolean isUndo;
    private ArrayList<PathPaint> linkedList = new ArrayList<>();

    private Bitmap mClearBitmap;

    private int mCurrentIndex = -1;

    public PaletteView(Context context) {
        this(context, null);
    }

    public PaletteView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PaletteView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {

    }

    private Paint step() {
        Paint mPaint = new Paint();
        mPaint.setColor(mPaintColor);
        mPaint.setDither(false);//关闭抖动
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(3f);
        mPaint.setAntiAlias(true);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setTypeface(Typeface.SERIF);
        return mPaint;
    }

    //如果view不处理down事件，那么后面的事件，也不再触发
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                final PathPaint pp = new PathPaint(new Path(), step());
                linkedList.add(pp);
                mCurrentIndex++;
                linkedList.get(mCurrentIndex).path.moveTo(x, y);
                break;
            case MotionEvent.ACTION_MOVE://mPath.lineTo(moveX, moveY);
                linkedList.get(mCurrentIndex).path.quadTo(x, y, x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        if (isUndo) {
            //清空画板
            clearCanvas(canvas);
            drawPathList(canvas);
            isUndo = false;
        } else {
            //start your own drawing
            drawPathList(canvas);
        }
    }

    private void drawPathList(Canvas canvas) {
        for (PathPaint drawPath : linkedList) {
            canvas.drawPath(drawPath.path, drawPath.paint);
        }
    }

    /**
     * 撤销:
     * <p/>
     * 1.将画布清空
     * 2.将保存下来的最后一个Path移除
     * 3.重新将剩余的Path画在画布上
     */
    public void undo() {
        // 移除最后一个path,相当于出栈操作
        if (linkedList.size() > 0) {
            linkedList.remove(linkedList.size() - 1);
            isUndo = true;
            mCurrentIndex--;
            invalidate();
        }
    }

    public void save() {
        setDrawingCacheEnabled(true);
        Bitmap mBitmap = bitmapBackgroundTransformer(getDrawingCache(), Color.WHITE);

        final File file = new File(Environment.getExternalStorageDirectory(), "paintutil");
        if (!file.exists()) {
            file.mkdirs();
        }
        final File saveFile = new File(file,
                "IMG" + System.currentTimeMillis() + ".png");

        FileOutputStream out = null;
        try {
            out = new FileOutputStream(saveFile);
            mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                setDrawingCacheEnabled(false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将bitmap的底背景颜色，转化成指定的颜色，并且保持内容部分不变
     *
     * @param bitmap
     * @return
     */
    private Bitmap bitmapBackgroundTransformer(Bitmap bitmap, int color) {
        /**
         * 1.如果保存格式是JPEG的话，那么缩略图和图片 底层颜色全都是黑色背景
         *
         * 2.如果保存格式是PNG的话，那么缩略图是白色，图片依然是黑色背景底
         *
         * 分析：
         * 问题出现的原因：在保存Bitmap为图片的时候，没有内容的区域，会默认为黑色填充，所以导致图片底是黑色的
         * 解决办法：最安全的解决方法
         * step1：首先创建一个纯白色的Bitmap
         * step2：用bitmap.extractAlpha()提取原Bitmap的内容部分
         * step3：用Canvas将原Bitmap的内容部分，绘制到 纯白色Bitmap上
         */
        Bitmap b = Bitmap.createBitmap(getWindowWidth(getContext()), getWindowHeight(getContext()), Bitmap.Config.ARGB_8888);
        int height = b.getHeight();
        int width = b.getWidth();
        int[] pixels = new int[width * height];
        for (int i = 0; i < height; i++)
            for (int j = 0; j < width; j++) {
                int index = i * width + j;
                pixels[index] = color;
            }
        b.setPixels(pixels, 0, width, 0, 0, width, height);

        //将原bitmap的内容区域，绘制到纯白色bitmap上
        Canvas canvas = new Canvas(b);
        Paint paint = new Paint();
        paint.setColor(mPaintColor);
        canvas.drawBitmap(bitmap.extractAlpha(), 0, 0, paint);
        return b;
    }

    /**
     * 清空canvas
     *
     * @param canvas
     */
    private void clearCanvas(Canvas canvas) {
        /**
         * 清空画板
         * Method_1.
         * Paint paint = new Paint();
         * paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
         * canvas.drawPaint(paint);
         * paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
         *
         * Method_2.
         * canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
         */
        mClearBitmap = Bitmap.createBitmap(getWindowWidth(getContext()), getWindowHeight(getContext()), Bitmap.Config.ARGB_8888);
        canvas.drawBitmap(mClearBitmap, 0, 0, null);
    }

    private static final class PathPaint {
        private Path path;
        private Paint paint;

        PathPaint(Path path, Paint paint) {
            this.path = path;
            this.paint = paint;
        }
    }

    private int getWindowWidth(Context ctx) {
        Display display = ((WindowManager) ctx
                .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);

        return metrics.widthPixels;
    }

    private int getWindowHeight(Context ctx) {

        Display display = ((WindowManager) ctx
                .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);

        return metrics.heightPixels;
    }
}
